package com.whu.UVAProtocol;


import com.whu.util.ByteUtil;
import com.whu.util.CRC16Util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

/**
 * @Description
 * @Author chengeng
 * @Date 2021/10/28 17:02
 **/
public class UVAMessageProtocolWrapper {

    public static final short MAGIC_NUMBER = 0x6868;

    public static final short DIR_MASK = 0x80;
    public static final short DIV_MASK = 0x40;
    public static final short OP_MASK = 0x0f;


    private UVAMessageProtocolType1_3 protocolType1_3;

    public UVAMessageProtocolType1_3 getProtocolType1_3() {
        return protocolType1_3;
    }

    public void setProtocolType1_3(UVAMessageProtocolType1_3 protocolType1_3) {
        this.protocolType1_3 = protocolType1_3;
    }

    public UVAMessageProtocolWrapper(UVAMessageProtocolType1_3 protocolType1_3) {
        this.protocolType1_3 = protocolType1_3;
    }

    /**
     * @Description:检验约定字符是否合法
     * @Param []
     * @return boolean
     * @Author chengeng
     * @Date 2021/10/18 17:00
     **/
    public boolean isValidMagicNumber(){
        return protocolType1_3.getMagicNumber()==MAGIC_NUMBER;
    }

    /**
     * @Description:检验接受的消息是否出错
     * @Param []
     * @return boolean {true:消息无误，false:发生错误}
     * @Author chengeng
     * @Date 2021/10/18 16:54
     **/
    public boolean checkCRC(){
        boolean res = false;
        byte[] checkData = protocol2Array();
        short crc = CRC16Util.getCRC(checkData);
        if(crc==protocolType1_3.getCrcCheckNum()){
            res = true;
        }else {
            res = false;
        }
        return res;
    }

    /**
     * @Description:将UVAMessageProtocolType1_3实例中除CRC校验码外的所有字段转化为byte数组
     * @Param []
     * @return byte[]
     * @Author chengeng
     * @Date 2021/10/18 16:52
     **/
    public byte[] protocol2Array(){
        ByteBuf buf = Unpooled.buffer();
        buf.writeShort(protocolType1_3.getMagicNumber());
        buf.writeByte(protocolType1_3.getAddressProp());
        buf.writeByte(protocolType1_3.getControlProp());
        buf.writeBytes(protocolType1_3.getDivs());
        buf.writeChar(protocolType1_3.getSerialNum());
        buf.writeShort(protocolType1_3.getMsgBodyLen());
        buf.writeBytes(protocolType1_3.getMsgBody());
        buf.writeDouble(protocolType1_3.getLongitude());
        buf.writeDouble(protocolType1_3.getLatitude());
        buf.writeFloat(protocolType1_3.getHeight());
        buf.writeByte(protocolType1_3.getBattery());
        buf.writeBytes(protocolType1_3.getTimeStamp());
        byte[] bytes = new byte[buf.readableBytes()];
        buf.readBytes(bytes);
        buf.release();//释放buf
        return bytes;
    }
    public byte[] protocol2Array0(){
        ByteBuf buf = Unpooled.buffer();
        buf.writeShort(protocolType1_3.getMagicNumber());
        buf.writeByte(protocolType1_3.getControlProp());
        buf.writeBytes(protocolType1_3.getDivs());
        buf.writeChar(protocolType1_3.getSerialNum());
        buf.writeShort(protocolType1_3.getMsgBodyLen());
        buf.writeBytes(protocolType1_3.getMsgBody());
        byte[] bytes = new byte[buf.readableBytes()];
        buf.readBytes(bytes);
        buf.release();//释放buf
        return bytes;
    }

    /**
     * @Description:得到控制域中的DIR字段的值,java端期望返回0
     * @Param []
     * @return short {1：J->C,0:C->J}
     * @Author chengeng
     * @Date 2021/10/18 17:21
     **/
    public short getDIR(){
        short dir = 0;
        dir = (short) (((protocolType1_3.getControlProp())&DIR_MASK)>>7);
        return dir;
    }

    /**
     * @Description:获取控制域中的DIV字段判断是否分帧
     * @Param []
     * @return short {0：不分帧传输，1：分帧传输}
     * @Author chengeng
     * @Date 2021/10/18 17:25
     **/
    public short getDIV(){
        short div = 0;
        div = (short) ((protocolType1_3.getControlProp()&DIV_MASK)>>6);
        return div;
    }

    /**
     * @Description:获取控制域中的操作码OP
     * @Param []
     * @return short {
     *     操作码类型0-15
     * }
     * @Author chengeng
     * @Date 2021/10/18 17:28
     **/
    public short getOP(){
        short op = 0;
        op = (short) (protocolType1_3.getControlProp()&OP_MASK);
        return op;
    }
    /**
     * @Description；从divs中得到总包数
     * @Param []
     * @return short
     * @Author chengeng
     * @Date 2021/11/12 14:05
     **/
    public int getTotalPckNum(){
        byte[] totalNum = {0x00,0x00,protocolType1_3.getDivs()[0],protocolType1_3.getDivs()[1]};
        int total = ByteUtil.getInt(totalNum);
        return total;
    }
    /**
     * @Description:从divs中得到当前包序列号
     * @Param []
     * @return short
     * @Author chengeng
     * @Date 2021/11/12 14:07
     **/

    public int getPckNum(){
        byte[] serialNum = {0x00,0x00,protocolType1_3.getDivs()[2],protocolType1_3.getDivs()[3]};
        int pckSerialNum = ByteUtil.getInt(serialNum);
        return pckSerialNum;
    }


}
